package cs2114.antiFingerMines;

import android.view.Menu;
import android.view.MenuInflater;
import android.content.Intent;
import android.view.MenuItem;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.TextView;

// -------------------------------------------------------------------------
/**
 *  This activity is the hardest game mode for Anti Finger Mines where the
 *  mines are invisible
 *
 *  @author Blake Whaley
 *  @author Graham McLaughlin (gjm1324)
 *  @author William Vuong (wnvuong)
 *  @version 2012.29.4
 */
public class AntiFingerMinesHard
    extends Activity
    implements OnTouchListener
{

    // ~ Instance/static variables .............................................
    private MineField           model;
    private MineField           invis;
    private AntiFingerMinesView mineView;
    private TextView            statusLabel;
    private float               width;
    private float               height;
    private String              status;

    // These variables represent ids for alert dialogs represent
    // a lost or a win in the game.
    static final int            GAME_LOST        = 0;
    static final int            GAME_WON         = 1;
    private static final int    RESULT_CLOSE_ALL = 1;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.game);
        mineView = (AntiFingerMinesView)findViewById(R.id.mineView);
        // Sets the view to be watched by this actvitiy class
        mineView.setOnTouchListener(AntiFingerMinesHard.this);
        // Stores the display info used to get the height and width
        Display display =
            ((WindowManager)getSystemService(Context.WINDOW_SERVICE))
                .getDefaultDisplay();
        // Stores the width and height of the view
        width = display.getWidth();
        height = display.getHeight();
        // Creates a new model with the width, height, and 30 mines
        model = new MineField(width, height, 15);

        // Sets the model so that the view can access it.
        mineView.setModel(model);

        // Sets the drawn model to be nothing as this is hard mode
        mineView.setVisible(false);

        statusLabel = (TextView)findViewById(R.id.statusLabel);
        setStatusText("Traverse the Minefield to the Green box to win!");
        statusLabel.setText("Traverse the Minefield to the Green box to win!");

    }


    /**
     * This method constantly calls isGameOver to see if the user has hit a
     * mine. if the user has hit a mine, it shows the dialog corresponding to
     * losing the game
     */
    public boolean onTouch(View v, MotionEvent event)
    {
        boolean handled = false;
        statusLabel.setText(Float.toString(model.distanceToClosestMine()/10));
        if (model.hasWon())
        {
            showDialog(GAME_WON);
            handled = true;
        }

        else if (model.isGameOver())
        {
            // Shows the alert dialog
            showDialog(GAME_LOST);
            handled = true;

        }
        return handled;
    }

    /**
     * Creates the option menu when the activity is created
     * @return boolean true when it is created
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        return true;
    }

    /**
     * Creates the options that will be shown
     * when the menu button is pressed
     * @return boolean is if an item has been selected
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId())
        {
            case R.id.Restart:
                // Creates a new game
                model.newGame(width, height, 15);
                // Tells the view to update the app with the new
                // mine field.
                mineView.invalidate();
                statusLabel.setText("Traverse the Minefield!");
                setStatusText("Traverse the Minefield!");
                break;
            case R.id.Difficulty:
                Intent MainMenu =
                    new Intent(
                        AntiFingerMinesHard.this,
                        AntiFingerMinesMenu.class);
                startActivity(MainMenu);
                break;
            case R.id.Quit:
                AntiFingerMinesHard.this.finish();
                AntiFingerMinesHard.this.moveTaskToBack(true);
                setResult(RESULT_CLOSE_ALL);
                break;
        }
        return true;
    }


    /**
     * This creates alert dialogs which will be then called by the ontouch
     * method depending on if the game is won or lost
     *
     * @param id
     *            is used to distinguish between the two dialog boxes represent
     *            a lost or a win.
     * @return Dialog is the dialog box
     */
    protected Dialog onCreateDialog(int id)
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        AlertDialog alert = null;
        switch (id)
        {
            case GAME_LOST:
                // sets the message title of the dialog
                builder.setMessage("You have lost the game")
                // setCancelable false means you cannot use the back
                // back button to exit the dialog
                    .setCancelable(false)
                    // set positive/neutral/negative button defines an action
                    // when the user selects this button. you are only
                    // allowed three buttons. The fact that you name it
                    // positive, negative or neutral is no different
                    // except for you the coder to know what is going on.
                    // The names are irrelevant to actual functionality

                    // this button labeled restart will restart the game
                    // with a new mine field
                    .setPositiveButton(
                        "Restart",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id1)
                            {
                                // Creates a new game
                                model.newGame(width, height, 15);
                                // Tells the view to update the app with the new
                                // mine field.
                                mineView.invalidate();
                                statusLabel.setText("Traverse the Minefield!");
                                setStatusText("Traverse the Minefield!");
                                dialog.cancel();
                            }
                        })

                    // this button labeled quit will allow the user to quit
                    // the game completely we can remove or change any of
                    // these buttons and add a third one.
                    .setNegativeButton(
                        "Main Menu",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id1)
                            {
                                // This line exits the activity which brings
                                // you to the main menu
                                AntiFingerMinesHard.this.finish();
                            }
                        });
                alert = builder.create();
                break;
            case GAME_WON:
                // This alert dialog functions the same as the other one except
                // it states that you have won the game
                builder
                    .setMessage("You have won the game")
                    .setCancelable(false)
                    .setPositiveButton(
                        "New Field",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id1)
                            {
                                model.newGame(width, height, 15);
                                mineView.invalidate();
                                statusLabel.setText("Traverse the Minefield!");
                                setStatusText("Traverse the Minefield!");
                                dialog.cancel();
                            }
                        })
                    .setNegativeButton(
                        "Main Menu",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id1)
                            {
                                AntiFingerMinesHard.this.finish();
                            }
                        });
                alert = builder.create();
                break;
            default:
                alert = null;
        }
        return alert;
    }

    /**
     * Returns the model.
     *
     * @return the model.
     */
    public MineField getModel()
    {
        return model;
    }

    /**
     * Gets the status text for testing purposes
     * @return the status
     */
    public String getStatusText()
    {
        return status;
    }

    /**
     * Sets the status text for testing purposes
     * @param status the status to set
     */
    public void setStatusText(String status)
    {
        this.status = status;
    }
}
